home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / libtiff / tif_read.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-19  |  16.0 KB  |  588 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_read.c,v 1.38 91/08/19 14:40:46 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991 Sam Leffler
  7.  * Copyright (c) 1991 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  * Scanline-oriented Read Support
  32.  */
  33. #include "tiffioP.h"
  34.  
  35. #if USE_PROTOTYPES
  36. static    TIFFSeek(TIFF *, u_int, u_int);
  37. static    int TIFFReadRawStrip1(TIFF *, u_int, u_char *, u_int, char []);
  38. static    int TIFFReadRawTile1(TIFF *, u_int, u_char *, u_int, char []);
  39. static    TIFFFillStrip(TIFF *, u_int);
  40. static    TIFFFillTile(TIFF *, u_int);
  41. static    TIFFStartStrip(TIFF *, u_int);
  42. static    TIFFStartTile(TIFF *, u_int);
  43. static    TIFFCheckRead(TIFF *, int);
  44. #else
  45. static    TIFFSeek();
  46. static    int TIFFReadRawStrip1();
  47. static    int TIFFReadRawTile1();
  48. static    TIFFFillStrip();
  49. static    TIFFFillTile();
  50. static    TIFFStartStrip();
  51. static    TIFFStartTile();
  52. static    TIFFCheckRead();
  53. #endif
  54.  
  55. /*VARARGS3*/
  56. TIFFReadScanline(tif, buf, row, sample)
  57.     register TIFF *tif;
  58.     u_char *buf;
  59.     u_int row, sample;
  60. {
  61.     int e;
  62.  
  63.     if (!TIFFCheckRead(tif, 0))
  64.         return (-1);
  65.     if (e = TIFFSeek(tif, row, sample)) {
  66.         /*
  67.          * Decompress desired row into user buffer.
  68.          */
  69.         e = (*tif->tif_decoderow)(tif, buf, tif->tif_scanlinesize, sample);
  70.         tif->tif_row++;
  71.     }
  72.     return (e ? 1 : -1);
  73. }
  74.  
  75. /*
  76.  * Seek to a random row+sample in a file.
  77.  */
  78. static
  79. /*VARARGS2*/
  80. TIFFSeek(tif, row, sample)
  81.     register TIFF *tif;
  82.     u_int row, sample;
  83. {
  84.     register TIFFDirectory *td = &tif->tif_dir;
  85.     int strip;
  86.  
  87.     if (row >= td->td_imagelength) {    /* out of range */
  88.         TIFFError(tif->tif_name, "%d: Row out of range, max %d",
  89.             row, td->td_imagelength);
  90.         return (0);
  91.     }
  92.     if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  93.         if (sample >= td->td_samplesperpixel) {
  94.             TIFFError(tif->tif_name,
  95.                 "%d: Sample out of range, max %d",
  96.                 sample, td->td_samplesperpixel);
  97.             return (0);
  98.         }
  99.         strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
  100.     } else
  101.         strip = row / td->td_rowsperstrip;
  102.     if (strip != tif->tif_curstrip) {     /* different strip, refill */
  103.         if (!TIFFFillStrip(tif, strip))
  104.             return (0);
  105.     } else if (row < tif->tif_row) {
  106.         /*
  107.          * Moving backwards within the same strip: backup
  108.          * to the start and then decode forward (below).
  109.          *
  110.          * NB: If you're planning on lots of random access within a
  111.          * strip, it's better to just read and decode the entire
  112.          * strip, and then access the decoded data in a random fashion.
  113.          */
  114.         if (!TIFFStartStrip(tif, strip))
  115.             return (0);
  116.     }
  117.     if (row != tif->tif_row) {
  118.         if (tif->tif_seek) {
  119.             /*
  120.              * Seek forward to the desired row.
  121.              */
  122.             if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  123.                 return (0);
  124.             tif->tif_row = row;
  125.         } else {
  126.             TIFFError(tif->tif_name,
  127.             "Compression algorithm does not support random access");
  128.             return (0);
  129.         }
  130.     }
  131.     return (1);
  132. }
  133.  
  134. /*
  135.  * Read a strip of data and decompress the specified
  136.  * amount into the user-supplied buffer.
  137.  */
  138. TIFFReadEncodedStrip(tif, strip, buf, size)
  139.     TIFF *tif;
  140.     u_int strip;
  141.     u_char *buf;
  142.     u_int size;
  143. {
  144.     TIFFDirectory *td = &tif->tif_dir;
  145.  
  146.     if (!TIFFCheckRead(tif, 0))
  147.         return (-1);
  148.     if (strip >= td->td_nstrips) {
  149.         TIFFError(tif->tif_name, "%d: Strip out of range, max %d",
  150.             strip, td->td_nstrips);
  151.         return (-1);
  152.     }
  153.     if (size == (u_int)-1)
  154.         size = td->td_rowsperstrip * tif->tif_scanlinesize;
  155.     else if (size > td->td_rowsperstrip * tif->tif_scanlinesize)
  156.         size = td->td_rowsperstrip * tif->tif_scanlinesize;
  157.     return (TIFFFillStrip(tif, strip) && 
  158.     (*tif->tif_decodestrip)(tif, buf, size, strip / td->td_stripsperimage) ?
  159.         size : -1);
  160. }
  161.  
  162. /*
  163.  * Read a strip of data from the file.
  164.  */
  165. TIFFReadRawStrip(tif, strip, buf, size)
  166.     TIFF *tif;
  167.     u_int strip;
  168.     u_char *buf;
  169.     u_int size;
  170. {
  171.     static char module[] = "TIFFReadRawStrip";
  172.     TIFFDirectory *td = &tif->tif_dir;
  173.     u_long bytecount;
  174.  
  175.     if (!TIFFCheckRead(tif, 0))
  176.         return (-1);
  177.     if (strip >= td->td_nstrips) {
  178.         TIFFError(tif->tif_name, "%d: Strip out of range, max %d",
  179.             strip, td->td_nstrips);
  180.         return (-1);
  181.     }
  182.     bytecount = td->td_stripbytecount[strip];
  183.     if (size == (u_int)-1)
  184.         size = bytecount;
  185.     else if (bytecount > size)
  186.         bytecount = size;
  187.     return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
  188. }
  189.  
  190. static int
  191. TIFFReadRawStrip1(tif, strip, buf, size, module)
  192.     TIFF *tif;
  193.     u_int strip;
  194.     u_char *buf;
  195.     u_int size;
  196.     char module[];
  197. {
  198.     TIFFDirectory *td = &tif->tif_dir;
  199.  
  200.     if (!isMapped(tif)) {
  201.         if (!SeekOK(tif->tif_fd, td->td_stripoffset[strip])) {
  202.             TIFFError(module,
  203.                 "%s: Seek error at scanline %d, strip %d",
  204.                 tif->tif_name, tif->tif_row, strip);
  205.             return (-1);
  206.         }
  207.         if (!ReadOK(tif->tif_fd, buf, size)) {
  208.             TIFFError(module, "%s: Read error at scanline %d",
  209.                 tif->tif_name, tif->tif_row);
  210.             return (-1);
  211.         }
  212. #ifdef MMAP_SUPPORT
  213.     } else {
  214.         if (td->td_stripoffset[strip] + size > tif->tif_size) {
  215.             TIFFError(module,
  216.                 "%s: Seek error at scanline %d, strip %d",
  217.                 tif->tif_name, tif->tif_row, strip);
  218.             return (-1);
  219.         }
  220.         bcopy(tif->tif_base + td->td_stripoffset[strip], buf, size);
  221. #endif
  222.     }
  223.     return (size);
  224. }
  225.  
  226. /*
  227.  * Read the specified strip and setup for decoding. 
  228.  * The data buffer is expanded, as necessary, to
  229.  * hold the strip's data.
  230.  */
  231. static
  232. TIFFFillStrip(tif, strip)
  233.     TIFF *tif;
  234.     u_int strip;
  235. {
  236.     static char module[] = "TIFFFillStrip";
  237.     TIFFDirectory *td = &tif->tif_dir;
  238.     u_long bytecount;
  239.  
  240.     bytecount = td->td_stripbytecount[strip];
  241. #ifdef MMAP_SUPPORT
  242.     if (isMapped(tif) &&
  243.         (td->td_fillorder == tif->tif_fillorder || (tif->tif_flags & TIFF_NOBITREV))) {
  244.         /*
  245.          * The image is mapped into memory and we either don't
  246.          * need to flip bits or the compression routine is going
  247.          * to handle this operation itself.  In this case, avoid
  248.          * copying the raw data and instead just reference the
  249.          * data from the memory mapped file image.  This assumes
  250.          * that the decompression routines do not modify the
  251.          * contents of the raw data buffer (if they try to,
  252.          * the application will get a fault since the file is
  253.          * mapped read-only).
  254.          */
  255.         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
  256.             free(tif->tif_rawdata);
  257.         tif->tif_flags &= ~TIFF_MYBUFFER;
  258.         if (td->td_stripoffset[strip] + bytecount > tif->tif_size) {
  259.             tif->tif_curstrip = -1;        /* unknown state */
  260.             return (0);
  261.         }
  262.         tif->tif_rawdatasize = bytecount;
  263.         tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip];
  264.     } else {
  265. #endif
  266.         /*
  267.          * Expand raw data buffer, if needed, to
  268.          * hold data strip coming from file
  269.          * (perhaps should set upper bound on
  270.          *  the size of a buffer we'll use?).
  271.          */
  272.         if (bytecount > tif->tif_rawdatasize) {
  273.             tif->tif_curstrip = -1;        /* unknown state */
  274.             if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
  275.                 TIFFError(module,
  276.                 "%s: Data buffer too small to hold strip %d",
  277.                     tif->tif_name, strip);
  278.                 return (0);
  279.             }
  280.             if (!TIFFReadBufferSetup(tif, 0,
  281.                 roundup(bytecount, 1024)))
  282.                 return (0);
  283.         }
  284.         if (TIFFReadRawStrip1(tif, strip, (u_char *)tif->tif_rawdata,
  285.             bytecount, module) != bytecount)
  286.             return (0);
  287.         if (td->td_fillorder != tif->tif_fillorder &&
  288.             (tif->tif_flags & TIFF_NOBITREV) == 0)
  289.             TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  290. #ifdef MMAP_SUPPORT
  291.     }
  292. #endif
  293.     return (TIFFStartStrip(tif, strip));
  294. }
  295.  
  296. /*
  297.  * Tile-oriented Read Support
  298.  * Contributed by Nancy Cam (Silicon Graphics).
  299.  */
  300.  
  301. /*
  302.  * Read and decompress a tile of data.  The
  303.  * tile is selected by the (x,y,z,s) coordinates.
  304.  */
  305. TIFFReadTile(tif, buf, x, y, z, s)
  306.     TIFF *tif;
  307.     u_char *buf;
  308.     u_long x, y, z;
  309.     u_int s;
  310. {
  311.     u_int tile;
  312.  
  313.     if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
  314.         return (-1);
  315.     tile = TIFFComputeTile(tif, x, y, z, s);
  316.     if (tile >= tif->tif_dir.td_nstrips) {
  317.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  318.             tile, tif->tif_dir.td_nstrips);
  319.         return (-1);
  320.     }
  321.     return (TIFFFillTile(tif, tile) &&
  322.         (*tif->tif_decodetile)(tif, buf, tif->tif_tilesize, s) ?
  323.         tif->tif_tilesize : -1);
  324. }
  325.  
  326. /*
  327.  * Read a tile of data and decompress the specified
  328.  * amount into the user-supplied buffer.
  329.  */
  330. TIFFReadEncodedTile(tif, tile, buf, size)
  331.     TIFF *tif;
  332.     u_int tile;
  333.     u_char *buf;
  334.     u_int size;
  335. {
  336.     TIFFDirectory *td = &tif->tif_dir;
  337.     int tilesize = tif->tif_tilesize;
  338.  
  339.     if (!TIFFCheckRead(tif, 1))
  340.         return (-1);
  341.     if (tile >= td->td_nstrips) {
  342.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  343.             tile, td->td_nstrips);
  344.         return (-1);
  345.     }
  346.     if (size == (u_int)-1)
  347.         size = tilesize;
  348.     else if (size > tilesize )
  349.         size = tilesize;
  350.     return (TIFFFillTile(tif, tile) && 
  351.         (*tif->tif_decodetile)(tif, buf, size, tile/td->td_stripsperimage) ?
  352.         size : -1);
  353. }
  354.  
  355. /*
  356.  * Read a tile of data from the file.
  357.  */
  358. TIFFReadRawTile(tif, tile, buf, size)
  359.     TIFF *tif;
  360.     u_int tile;
  361.     u_char *buf;
  362.     u_int size;
  363. {
  364.     static char module[] = "TIFFReadRawTile";
  365.     TIFFDirectory *td = &tif->tif_dir;
  366.     u_long bytecount;
  367.  
  368.     if (!TIFFCheckRead(tif, 1))
  369.         return (-1);
  370.     if (tile >= td->td_nstrips) {
  371.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  372.             tile, td->td_nstrips);
  373.         return (-1);
  374.     }
  375.     bytecount = td->td_stripbytecount[tile];
  376.     if (size == (u_int)-1)
  377.         size = bytecount;
  378.     else if (bytecount > size)
  379.         bytecount = size;
  380.     return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));
  381. }
  382.  
  383. static int
  384. TIFFReadRawTile1(tif, tile, buf, size, module)
  385.     TIFF *tif;
  386.     u_int tile;
  387.     u_char *buf;
  388.     u_int size;
  389.     char module[];
  390. {
  391.     TIFFDirectory *td = &tif->tif_dir;
  392.  
  393.     if (!isMapped(tif)) {
  394.         if (!SeekOK(tif->tif_fd, td->td_stripoffset[tile])) {
  395.             TIFFError(module,
  396.                 "%s: Seek error at row %d, col %d, tile %d",
  397.                 tif->tif_name, tif->tif_row, tif->tif_col, tile);
  398.             return (-1);
  399.         }
  400.         if (!ReadOK(tif->tif_fd, buf, size)) {
  401.             TIFFError(module, "%s: Read error at row %d, col %d",
  402.                 tif->tif_name, tif->tif_row, tif->tif_col);
  403.             return (-1);
  404.         }
  405. #ifdef MMAP_SUPPORT
  406.     } else {
  407.         if (td->td_stripoffset[tile] + size > tif->tif_size) {
  408.             TIFFError(module,
  409.                 "%s: Seek error at row %d, col %d, tile %d",
  410.                 tif->tif_name, tif->tif_row, tif->tif_col, tile);
  411.             return (-1);
  412.         }
  413.         bcopy(tif->tif_base + td->td_stripoffset[tile], buf, size);
  414. #endif
  415.     }
  416.     return (size);
  417. }
  418.  
  419. /*
  420.  * Read the specified tile and setup for decoding. 
  421.  * The data buffer is expanded, as necessary, to
  422.  * hold the tile's data.
  423.  */
  424. static
  425. TIFFFillTile(tif, tile)
  426.     TIFF *tif;
  427.     u_int tile;
  428. {
  429.     static char module[] = "TIFFFillTile";
  430.     TIFFDirectory *td = &tif->tif_dir;
  431.     u_long bytecount;
  432.  
  433.     bytecount = td->td_stripbytecount[tile];
  434. #ifdef MMAP_SUPPORT
  435.     if (isMapped(tif) &&
  436.         (td->td_fillorder == tif->tif_fillorder || (tif->tif_flags & TIFF_NOBITREV))) {
  437.         /*
  438.          * The image is mapped into memory and we either don't
  439.          * need to flip bits or the compression routine is going
  440.          * to handle this operation itself.  In this case, avoid
  441.          * copying the raw data and instead just reference the
  442.          * data from the memory mapped file image.  This assumes
  443.          * that the decompression routines do not modify the
  444.          * contents of the raw data buffer (if they try to,
  445.          * the application will get a fault since the file is
  446.          * mapped read-only).
  447.          */
  448.         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
  449.             free(tif->tif_rawdata);
  450.         tif->tif_flags &= ~TIFF_MYBUFFER;
  451.         if (td->td_stripoffset[tile] + bytecount > tif->tif_size) {
  452.             tif->tif_curtile = -1;        /* unknown state */
  453.             return (0);
  454.         }
  455.         tif->tif_rawdatasize = bytecount;
  456.         tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile];
  457.     } else {
  458. #endif
  459.         /*
  460.          * Expand raw data buffer, if needed, to
  461.          * hold data tile coming from file
  462.          * (perhaps should set upper bound on
  463.          *  the size of a buffer we'll use?).
  464.          */
  465.         if (bytecount > tif->tif_rawdatasize) {
  466.             tif->tif_curtile = -1;        /* unknown state */
  467.             if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
  468.                 TIFFError(module,
  469.                 "%s: Data buffer too small to hold tile %d",
  470.                     tif->tif_name, tile);
  471.                 return (0);
  472.             }
  473.             if (!TIFFReadBufferSetup(tif, 0,
  474.                 roundup(bytecount, 1024)))
  475.                 return (0);
  476.         }
  477.         if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata,
  478.             bytecount, module) != bytecount)
  479.             return (0);
  480.         if (td->td_fillorder != tif->tif_fillorder &&
  481.             (tif->tif_flags & TIFF_NOBITREV) == 0)
  482.             TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  483. #ifdef MMAP_SUPPORT
  484.     }
  485. #endif
  486.     return (TIFFStartTile(tif, tile));
  487. }
  488.  
  489. /*
  490.  * Setup the raw data buffer in preparation for
  491.  * reading a strip of raw data.  If the buffer
  492.  * is specified as zero, then a buffer of appropriate
  493.  * size is allocated by the library.  Otherwise,
  494.  * the client must guarantee that the buffer is
  495.  * large enough to hold any individual strip of
  496.  * raw data.
  497.  */
  498. int
  499. TIFFReadBufferSetup(tif, bp, size)
  500.     TIFF *tif;
  501.     char *bp;
  502.     u_int size;
  503. {
  504.     static char module[] = "TIFFReadBufferSetup";
  505.  
  506.     if (tif->tif_rawdata) {
  507.         if (tif->tif_flags & TIFF_MYBUFFER)
  508.             free(tif->tif_rawdata);
  509.         tif->tif_rawdata = NULL;
  510.     }
  511.     if (bp) {
  512.         tif->tif_rawdatasize = size;
  513.         tif->tif_rawdata = bp;
  514.         tif->tif_flags &= ~TIFF_MYBUFFER;
  515.     } else {
  516.         tif->tif_rawdatasize = roundup(size, 1024);
  517.         tif->tif_rawdata = malloc(tif->tif_rawdatasize);
  518.         tif->tif_flags |= TIFF_MYBUFFER;
  519.     }
  520.     if (tif->tif_rawdata == NULL) {
  521.         TIFFError(module,
  522.             "%s: No space for data buffer at scanline %d",
  523.             tif->tif_name, tif->tif_row);
  524.         tif->tif_rawdatasize = 0;
  525.         return (0);
  526.     }
  527.     return (1);
  528. }
  529.  
  530. /*
  531.  * Set state to appear as if a
  532.  * strip has just been read in.
  533.  */
  534. static
  535. TIFFStartStrip(tif, strip)
  536.     register TIFF *tif;
  537.     u_int strip;
  538. {
  539.     TIFFDirectory *td = &tif->tif_dir;
  540.  
  541.     tif->tif_curstrip = strip;
  542.     tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  543.     tif->tif_rawcp = tif->tif_rawdata;
  544.     tif->tif_rawcc = td->td_stripbytecount[strip];
  545.     return (tif->tif_predecode == NULL || (*tif->tif_predecode)(tif));
  546. }
  547.  
  548. /*
  549.  * Set state to appear as if a
  550.  * tile has just been read in.
  551.  */
  552. static
  553. TIFFStartTile(tif, tile)
  554.     register TIFF *tif;
  555.     u_int tile;
  556. {
  557.     TIFFDirectory *td = &tif->tif_dir;
  558.  
  559.     tif->tif_curtile = tile;
  560.     tif->tif_row =
  561.         (tile % howmany(td->td_imagewidth, td->td_tilewidth)) *
  562.         td->td_tilelength;
  563.     tif->tif_col =
  564.         (tile % howmany(td->td_imagelength, td->td_tilelength)) *
  565.         td->td_tilewidth;
  566.     tif->tif_rawcp = tif->tif_rawdata;
  567.     tif->tif_rawcc = td->td_stripbytecount[tile];
  568.     return (tif->tif_predecode == NULL || (*tif->tif_predecode)(tif));
  569. }
  570.  
  571. static
  572. TIFFCheckRead(tif, tiles)
  573.     TIFF *tif;
  574.     int tiles;
  575. {
  576.     if (tif->tif_mode == O_WRONLY) {
  577.         TIFFError(tif->tif_name, "File not open for reading");
  578.         return (0);
  579.     }
  580.     if (tiles ^ isTiled(tif)) {
  581.         TIFFError(tif->tif_name, tiles ?
  582.             "Can not read tiles from a stripped image" :
  583.             "Can not read scanlines from a tiled image");
  584.         return (0);
  585.     }
  586.     return (1);
  587. }
  588.